package glotton;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;

public class GlottonController implements Glotton {
	private String propertyFilename = "/defaults.txt";
	private List<String> dictionary;
    private String englishPropertyName = "wordfiles";
    private String norwegianPropertyName = "wordfiles_no";
	private Properties properties;
	private final Finder finder;
	
	public GlottonController(Finder f) {
        finder = f;
		setupDictionary();
        setDictionaryTo("en");
	}
	
	private void setupDictionary() {
        dictionary = new LinkedList<String>();
        new LinkedList<String>();
    }
	
	public void clearDictionary() {
		dictionary = new LinkedList<String>();
	}
	
	@Override
	public int getDictionarySize() {
		return dictionary != null ? dictionary.size() : 0;
	}
	
    public void setDictionaryTo(String language) {
    	clearDictionary();
    	
        setDictionaryFromResource(language);
    }

	private void setDictionaryFromResource(String language) {
		String[] resourcesToLoad = getResourceNamesFor(language);
		
		for (String resourceName : resourcesToLoad) {
			addResourceToDictionary(resourceName);
		}
	}

	private String[] getResourceNamesFor(String language) {
		properties = getPropertiesFromResource();
		
		String resourceNamesAsOneString;
		if (language == "no") {
			resourceNamesAsOneString = properties.getProperty(norwegianPropertyName);
		}
		else {
			resourceNamesAsOneString = properties.getProperty(englishPropertyName);
		}
		
		if (resourceNamesAsOneString == null) return new String[0];
		
		String[] resourcesToLoad = resourceNamesAsOneString.split(", ");
		return resourcesToLoad;
	}

	private Properties getPropertiesFromResource() {
		Properties properties = new java.util.Properties();
		InputStream propertiesStream = getClass().getResourceAsStream(propertyFilename);
        if (propertiesStream == null){ //The properties file does not exist
        	Logger.getLogger("global").log(Level.WARNING, "cannot load properties file - returning default properties object");
        	properties.setProperty(norwegianPropertyName, "/dist/no/nn-bigwordlist, /dist/no/norwegian.txt");
        	properties.setProperty(englishPropertyName, "/dist/scowl/final/english-words.10, /dist/scowl/final/english-words.20, /dist/scowl/final/english-words.35, /dist/scowl/final/english-words.40, /dist/scowl/final/english-words.50, /dist/scowl/final/english-words.55, /dist/scowl/final/english-words.60, /dist/scowl/final/english-words.70, /dist/scowl/final/english-words.80, /dist/scowl/final/english-words.95");
            return properties; 
        }
        
        try {
			properties.load(propertiesStream);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        
		return properties;
	}

	private void addResourceToDictionary(String resourceName) {
		InputStream norwegian = this.getClass().getResourceAsStream(resourceName);
		if (norwegian != null) {
			addToDictionary(norwegian);
		}
	}

	public void addToDictionary(InputStream words) {
		InputStreamReader reader = null;
		
		try {
			reader = new InputStreamReader(words);
			BufferedReader buffer = new BufferedReader(reader);
			
			while (buffer.ready()) {
				dictionary.add(buffer.readLine());
			}
		}catch (Exception ex) {
			System.err.println("Error when reading from inputstream " + words);
			System.out.println("Error in addToDictionary");
			ex.printStackTrace();
		} finally {
			try {
				if (reader != null) {
					reader.close();
				}
			} catch (IOException ex) {
				//stupid - throwing errors on close. What am I supposed to do about that?
			}
		}
	}
	
	@Override
	public void addToToDictionary(File newFile) {
		FileReader reader = null;
		try {
			reader = new FileReader(newFile);
			BufferedReader buffer = new BufferedReader(reader);
			
			while (buffer.ready()) {
				dictionary.add(buffer.readLine());
			}
		} catch (Exception ex) {
			System.err.println("Error when reading from file " + newFile.getName());
			System.out.println("Error in addToDictionary");
			ex.printStackTrace();
		} finally {
			try {
				if (reader != null) {
					reader.close();
				}
			} catch (IOException ex) {
				//stupid - throwing errors on close. What am I supposed to do about that?
			}
		}
	}

	@Override
	public void FindWords(String useableChars) {
		finder.setCharacters(useableChars);
		finder.setSearchSpace(dictionary);
		finder.setRequiredPattern("");
        Thread t = new Thread(finder);
        t.start();
		
	}

	@Override
	public void FindWordsWithPattern(String useableChars, String pattern) {
		finder.setCharacters(useableChars);
		finder.setSearchSpace(dictionary);
		finder.setRequiredPattern(pattern);
		System.out.println("Searching for words with pattern "+ pattern + " ...");
        Thread t = new Thread(finder);
        t.start();
	}

}
